<!DOCTYPE html>
<html>

<head>
    <title>垂直滚动的动态瀑布图示例</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }

        canvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: #f0f0f0;
        }
    </style>
</head>

<body>
<canvas id="waterfallCanvas"></canvas>
<script>
    const canvas = document.getElementById('waterfallCanvas');
    const ctx = canvas.getContext('2d');

    // 设置画布尺寸
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // 配置瀑布图参数
    const waterfallGraph = {
        width: canvas.width,
        height: canvas.height,
        numPoints: 256, // 数据点数
        pointWidth: 2, // 数据点宽度
        pointSpacing: 1, // 数据点间距
        maxPointValue: 100, // 数据点最大值
        data: [], // 数据数组
    };

    // 初始化数据数组
    for (let i = 0; i < waterfallGraph.numPoints; i++) {
        waterfallGraph.data.push(0);
    }

    // 更新数据数组
    function updateData() {
        // 模拟随机数据
        waterfallGraph.data.shift();
        waterfallGraph.data.push(Math.random() * waterfallGraph.maxPointValue);
    }

    // 绘制瀑布图
    function drawWaterfallGraph() {
        const {width, height, numPoints, pointWidth, pointSpacing, maxPointValue, data} = waterfallGraph;

        ctx.clearRect(0, 0, width, height);

        for (let i = 0; i < numPoints; i++) {
            const pointValue = data[i];
            const x = i * (pointWidth + pointSpacing);
            const y = height - pointValue;

            ctx.fillStyle = '#007bff';
            ctx.fillRect(x, y, pointWidth, pointValue);
        }

        updateData();

        // 每帧向上滚动一个像素
        const imageData = ctx.getImageData(0, 0, width, height);
        ctx.clearRect(0, 0, width, height);
        ctx.putImageData(imageData, 0, -1);

        requestAnimationFrame(drawWaterfallGraph);
    }

    // 调用绘制瀑布图函数
    drawWaterfallGraph();
</script>
</body>

</html>
